内存的单位：
	bit 一个bit位能存储1个二进制 内存的最小单位。
	1byte ＝ 8bit，一次性使用的最小单位，操作系统会为每个字节分配一个编号（天然按位置排列）。
	1kb ＝ 1024byte
	1mb ＝ 1024kb
	1gb ＝ 1024mb
	1tb ＝ 1024gb
	1pt ＝ 1024tb 
什么是指针：
	指针变量的取值范围取值0~4G
	指针是一种数据类型（无符号整数，代表了内存编号），使用它可以用来定义变量（与int、long一样），与int、long不同的它存储整数代表了内存的编号，通过这个变量可以访问对应编号的内存。

为什么使用指针:
	1、堆内存无法取名字（无法使用标识符与堆内存建立联系），必须配合指针。
	2、函数之间的参数是值传递（内存拷贝），使用指针可以优化参数的传递效率（需要对变量进行保护）。
			因为C语言采用的是值传递（内存拷贝），会随着变量字节数的增加而降低运行效率
			而传递变量的地址永远只拷贝4或8字节
			void func(const int* p);
			但使用指针变量的值可能会被修改，可以配合const
		
	3、函数之间是相互独立的，有时协同配合需要共享变量（全局变量过多会造成命名冲突，不会被释放浪费内存），函数之间传递变量的地址可以达到共享变量的效果。
		
如何使用指针：
	定义：类型* 变量名_p;  
		1、指针变量与普通变量一样默认值不确定，一般初始化为NULL。
		2、指针变量的用法与普通变量不同，一般以p结尾加以区分。
		3、指针变量的类型决定了通过指针变量访问内存时访问几个字节。
		4、指针变量不能连续定义（一个*只能定义出一个指针变量）：
			int* p1,p2; // p是指针，p2是int类型变量
			int *p1,*p2; // p1和p2都是指针变量
	赋值：指针变量 = 内存编号。
			变量名_p = 地址；
		1、类型要正确。
		2、内存编号要能够访问，如果编号错误可能会造成段错误。
		3、void*可以与任意类型指针进行自动转换（C++中不行）
		4、要保障地址与物理内存有对应关系（映射过），否则有段错误。
		int* p = malloc(4);
		int* p = &num; // 引用内存
	
	访问：*指针变量 //解引用----访问指针变量
		1、根据指针变量中存储的内存编号去访问对应的内存。
		2、如果之前赋值的内存编号有误，这个步骤会出现段错误。
		3、访问的字节由指针类型决定。
		int* p = &num;
		*p <=> num;
	
	
	练习1：定义一个函数，用来交换两个变量的值。
	练习2：定义一个函数，求两个整数的最大公约数和最小公倍数，
	最大公约数通过return返回，最小公倍数用指针处理。
	
使用指针要注意的问题
	1.空指针：
	变量指针的值等于NULL，这种指针叫空指针。
	不能对空指针解引用，一定会出现段错误。
	当操作重启时会跳转NULL地址，进行重启，因此NULL存储操作系统用于重启的数据。
	NULL在C语言中是一种错误标志，如果函数的返回值是指针类型，结果一旦NULL表示函数执行出错或失败。
	如何避免空指针造成的段错误？
	使用来历不明（函数的参数）的指针前先进行检查，if(NULL == p)。
	
	2.野指针：指针变量的值不确定，使用野指针不一定会出错。
	int* p; // 野指针
	使用野指针的后果：
		1、一切正常。
		2、脏数据。
		3、段错误。	
	注意：野指针是无法分辨的，所以比空指针危害更。
	如何避免野指针造成的错误？
	所有的野指针都人制造出来的，只要人人都不制造野指针就会有野指针造成的错误。
		1、定义指针变量时一定要初始化。
		2、指针变量所指向的内存初始释放后要及时赋值为空（堆内存）。
		3、不返回局部变量的地址。
	
指针的运算
	指针变量中存储的就是整数，因此为整型数据能使用的运算符指针变量基本都能使用，但不是所有运算都有意义。
	指针＋整数 ＝ 指针+宽度*整数
	指针－整数 ＝ 指针-宽度*整数 // 指针进行前后移动
	指针－指针 ＝ (指针-指针)/宽度 // 两个指针之间相隔多少个元素
	指针 >、<、<=、>= 指针 可以判断两个谁在前谁在后。
	
数组与指针
	1.数组名就是个特殊的地址，也能当指针使用，数组名是个常量（数组名与数组第一个元素的首地址是对应关系，普通指针是指向关系）。
	2.数组名可以使用指针的解引用，而指针变量也可以使用数组的[];
	arr[i] <=> *(arr+i)。
	3.数组当函数的参数就脱变成了指针变量，长度丢失，安全性也变小
	void func(int * const arr,size_t len);
	
指针与const的配合使用：
	const int* p
	int const *p;
	int * const p;
	const int * const p;
	int const * const p;
------------------------------------------------------
const 与 指针
	const int * p; // 不能通过解引用去修改指针所指向的内存的数据
		1、保护函数的参数
		2、当指针指向的是只读数据，也应该加上const防止出现段错误。
	int const * p; // 同上
	int* const p; // 不能修改指针变量的值
		可以防止指针变量意外变成野指针
	const int* const p; // 既保存指针所指针的内存，也保护指针变量
	int const * const p; // 同上
	
--------------------------------------------------------------------

指针的高级应用：

	数组指针与指针数组：
	
	1.数组指针(指针)：专门用来指向数组的指针。
	int arr[10];
	int (*p)[10] = arr;
	int* p = &num;
	
	void func(int I,int J,int(*arr)[J])  //二维数组 函数传参使用数组指针
	
	
	2.指针数组(数组)：一个数组里存储的数据类型是指针。
					把无序的离散数据，归纳到一起。
	int* arr[3]; <=> int *p1,*p2,*p3;

	3.二级值针： 指向指针的指针
	4.函数指针： 指向函数的指针（不能解引用）
	
	
	
	